package com.virus.server.catalina;

import com.virus.server.http.ApplicationFilterChain;
import com.virus.server.http.Request;
import com.virus.server.http.Response;
import com.virus.server.servlet.DefaultServlet;
import com.virus.server.servlet.DynamicServlet;
import com.virus.server.utils.SessionUtils;
import com.virus.server.utils.ThreadUtils;

import javax.servlet.Filter;
import javax.servlet.Servlet;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.List;

public class Connector implements Runnable {

    private int port;

    private Service service;

    public Connector(int port, Service service) {
        this.port = port;
        this.service = service;
    }

    public int getPort() {
        return port;
    }

    private void getSession(Request request, Response response) {
        String jsessionid = request.getJsessionidFromCookie();
        HttpSession session = SessionUtils.getSession(jsessionid, request, response);
        request.setSession(session);
    }

    @Override
    public void run() {
        try {
            ServerSocket serverSocket = new ServerSocket(port);
            System.out.println("starting connector, whose port is [" + port + "]");
            while (true) {
                Socket client = serverSocket.accept();
                Runnable runnable = new Runnable() {
                    @Override
                    public void run() {
                        Request request = new Request(client, service.getEngine());
                        Response response = new Response(client);
                        getSession(request, response);
                        String contextPath = request.getContextPath();
                        String servletPath = request.getServletPath();
                        System.out.println("访问应用为[" + contextPath + "],访问资源为[" + servletPath + "]");
                        //设置response的content type
                        try {
                            Servlet servlet = null;
                            getSession(request, response);
                            if (servletPath.equals("/")) {
                                servlet = DefaultServlet.INSTANCE;
                            } else {
                                String servletClass = request.getContext().getServletClass(servletPath);
                                servlet = DefaultServlet.INSTANCE;
                                if (servletClass != null) {
                                    servlet = DynamicServlet.INSTANCE;
                                }
                            }
                            List<Filter> filters = request.getContext().getFilters(servletPath);
                            ApplicationFilterChain applicationFilterChain = new ApplicationFilterChain(filters, servlet);
                            applicationFilterChain.doFilter(request, response);
                        } catch (Exception e) {
                            e.printStackTrace();
                            response.setStatus(500);
                            response.getWriter().println(e.toString());
                        } finally {
                            response.respond();
                        }
                    }
                };
                ThreadUtils.add(runnable);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
